package cn.powertime.evaluation.shiro.cacho;

import com.google.common.collect.Lists;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class RedisCache<K,V> implements Cache<K,V> {

    private static final Logger LOGGER = LoggerFactory.getLogger(RedisCache.class);

    private RedisTemplate<K,V> redisTemplate;
    private final static String PREFIX = "shiro:cache:";
    private String cacheKey;
    private long globExpire = 30;

    public RedisCache(final String name, final RedisTemplate redisTemplate){
        this.cacheKey = PREFIX+"name"+":";
        this.redisTemplate = redisTemplate;
    }

    @Override
    public V get(K k) throws CacheException {
        LOGGER.debug("cache get key:{}",k);
        redisTemplate.boundValueOps(getCacheKey(k)).expire(globExpire, TimeUnit.MINUTES);
        return redisTemplate.boundValueOps(getCacheKey(k)).get();
    }

    @Override
    public V put(K k, V v) throws CacheException {
        V oldValue = get(k);
        redisTemplate.boundValueOps(getCacheKey(k)).set(v);
        return oldValue;
    }

    @Override
    public V remove(K k) throws CacheException {
        V oldValue = get(k);
        redisTemplate.delete(getCacheKey(k));
        return oldValue;
    }

    @Override
    public void clear() throws CacheException {
        redisTemplate.delete(keys());
    }

    @Override
    public int size() {
        return keys().size();
    }

    @Override
    public Set<K> keys() {
        return redisTemplate.keys(getCacheKey("*"));
    }

    @Override
    public Collection<V> values() {
        Set<K> set = keys();
        List<V> list = Lists.newArrayList();
        for(K k : set){
            list.add(get(k));
        }
        return list;
    }

    private K getCacheKey(Object k){
        return (K)(this.cacheKey + k);
    }
}
